home *** CD-ROM | disk | FTP | other *** search
/ Aminet 1 (Walnut Creek) / Aminet - June 1993 [Walnut Creek].iso / aminet / util / gnu / fileutils_3_3.lha / fileutils-3.3 / lib / mountlist.c < prev    next >
C/C++ Source or Header  |  1992-08-01  |  10KB  |  403 lines

  1. /* mountlist.c -- return a list of mounted filesystems
  2.    Copyright (C) 1991, 1992 Free Software Foundation, Inc.
  3.  
  4.    This program is free software; you can redistribute it and/or modify
  5.    it under the terms of the GNU General Public License as published by
  6.    the Free Software Foundation; either version 2, or (at your option)
  7.    any later version.
  8.  
  9.    This program is distributed in the hope that it will be useful,
  10.    but WITHOUT ANY WARRANTY; without even the implied warranty of
  11.    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
  12.    GNU General Public License for more details.
  13.  
  14.    You should have received a copy of the GNU General Public License
  15.    along with this program; if not, write to the Free Software
  16.    Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.  */
  17.  
  18. #include <stdio.h>
  19. #include <sys/types.h>
  20. #include "mountlist.h"
  21.  
  22. #ifdef STDC_HEADERS
  23. #include <stdlib.h>
  24. #else
  25. void free ();
  26. #endif
  27. #if defined(USG) || defined(STDC_HEADERS)
  28. #include <string.h>
  29. #else
  30. #include <strings.h>
  31. #endif
  32.  
  33. char *strstr ();
  34. char *xmalloc ();
  35. char *xrealloc ();
  36. char *xstrdup ();
  37. void error ();
  38.  
  39. #ifdef MOUNTED_GETMNTENT1    /* 4.3BSD, SunOS, HP-UX, Dynix, Irix.  */
  40. #include <mntent.h>
  41. #if !defined(MOUNTED)
  42. #  if defined(MNT_MNTTAB)    /* HP-UX.  */
  43. #    define MOUNTED MNT_MNTTAB
  44. #  endif
  45. #  if defined(MNTTABNAME)    /* Dynix.  */
  46. #    define MOUNTED MNTTABNAME
  47. #  endif
  48. #endif
  49. #endif
  50.  
  51. #ifdef MOUNTED_GETMNTINFO    /* 4.4BSD.  */
  52. #include <sys/mount.h>
  53. #endif
  54.  
  55. #ifdef MOUNTED_GETMNT        /* Ultrix.  */
  56. #include <sys/param.h>
  57. #include <sys/mount.h>
  58. #include <sys/fs_types.h>
  59. #endif
  60.  
  61. #ifdef MOUNTED_FREAD        /* SVR2.  */
  62. #include <mnttab.h>
  63. #endif
  64.  
  65. #ifdef MOUNTED_FREAD_FSTYP    /* SVR3.  */
  66. #include <mnttab.h>
  67. #include <sys/fstyp.h>
  68. #include <sys/statfs.h>
  69. #endif
  70.  
  71. #ifdef MOUNTED_GETMNTENT2    /* SVR4.  */
  72. #include <sys/mnttab.h>
  73. #endif
  74.  
  75. #ifdef MOUNTED_VMOUNT        /* AIX.  */
  76. #include <fshelp.h>
  77. #include <sys/vfs.h>
  78. #endif
  79.  
  80. #ifdef MOUNTED_GETMNTENT1    /* 4.3BSD, SunOS, HP-UX, Dynix, Irix.  */
  81. /* Return the value of the hexadecimal number represented by CP.
  82.    No prefix (like '0x') or suffix (like 'h') is expected to be
  83.    part of CP. */
  84.  
  85. static int
  86. xatoi (cp)
  87.      char *cp;
  88. {
  89.   int val;
  90.   
  91.   val = 0;
  92.   while (*cp)
  93.     {
  94.       if (*cp >= 'a' && *cp <= 'f')
  95.     val = val * 16 + *cp - 'a' + 10;
  96.       else if (*cp >= 'A' && *cp <= 'F')
  97.     val = val * 16 + *cp - 'A' + 10;
  98.       else if (*cp >= '0' && *cp <= '9')
  99.     val = val * 16 + *cp - '0';
  100.       else
  101.     break;
  102.       cp++;
  103.     }
  104.   return val;
  105. }
  106. #endif /* MOUNTED_GETMNTENT1.  */
  107.  
  108. #ifdef MOUNTED_GETMNTINFO    /* 4.4BSD.  */
  109. static char *
  110. fstype_to_string (t)
  111.      short t;
  112. {
  113.   switch (t)
  114.     {
  115.     case MOUNT_UFS:
  116.       return "ufs";
  117.     case MOUNT_NFS:
  118.       return "nfs";
  119.     case MOUNT_PC:
  120.       return "pc";
  121. #ifdef MOUNT_MFS
  122.     case MOUNT_MFS:
  123.       return "mfs";
  124. #endif
  125. #ifdef MOUNT_LO
  126.     case MOUNT_LO:
  127.       return "lo";
  128. #endif
  129. #ifdef MOUNT_TFS
  130.     case MOUNT_TFS:
  131.       return "tfs";
  132. #endif
  133. #ifdef MOUNT_TMP
  134.     case MOUNT_TMP:
  135.       return "tmp";
  136. #endif
  137.     default:
  138.       return "?";
  139.     }
  140. }
  141. #endif /* MOUNTED_GETMNTINFO */
  142.  
  143. #ifdef MOUNTED_VMOUNT        /* AIX.  */
  144. static char *
  145. fstype_to_string (t)
  146.      int t;
  147. {
  148.   struct vfs_ent *e;
  149.  
  150.   e = getvfsbytype (t);
  151.   if (!e || !e->vfsent_name)
  152.     return "none";
  153.   else
  154.     return e->vfsent_name;
  155. }
  156. #endif /* MOUNTED_VMOUNT */
  157.  
  158. /* Return a list of the currently mounted filesystems, or NULL on error.
  159.    Add each entry to the tail of the list so that they stay in order.
  160.    If NEED_FS_TYPE is nonzero, ensure that the filesystem type fields in
  161.    the returned list are valid.  Otherwise, they might not be.
  162.    If ALL_FS is zero, do not return entries for filesystems that
  163.    are automounter (dummy) entries.  */
  164.  
  165. struct mount_entry *
  166. read_filesystem_list (need_fs_type, all_fs)
  167.      int need_fs_type, all_fs;
  168. {
  169.   struct mount_entry *mount_list;
  170.   struct mount_entry *me;
  171.   struct mount_entry *mtail;
  172.  
  173.   /* Start the list off with a dummy entry. */
  174.   me = (struct mount_entry *) xmalloc (sizeof (struct mount_entry));
  175.   me->me_next = NULL;
  176.   mount_list = mtail = me;
  177.  
  178. #ifdef MOUNTED_GETMNTENT1    /* 4.3BSD, SunOS, HP-UX, Dynix, Irix.  */
  179.   {
  180.     struct mntent *mnt;
  181.     char *table = MOUNTED;
  182.     FILE *fp;
  183.     char *devopt;
  184.  
  185.     fp = setmntent (table, "r");
  186.     if (fp == NULL)
  187.       return NULL;
  188.  
  189.     while ((mnt = getmntent (fp)))
  190.       {
  191.     if (!all_fs && (!strcmp (mnt->mnt_type, "ignore")
  192.             || !strcmp (mnt->mnt_type, "auto")))
  193.       continue;
  194.  
  195.     me = (struct mount_entry *) xmalloc (sizeof (struct mount_entry));
  196.     me->me_devname = xstrdup (mnt->mnt_fsname);
  197.     me->me_mountdir = xstrdup (mnt->mnt_dir);
  198.     me->me_type = xstrdup (mnt->mnt_type);
  199.     devopt = strstr (mnt->mnt_opts, "dev=");
  200.     if (devopt)
  201.       {
  202.         if (devopt[4] == '0' && (devopt[5] == 'x' || devopt[5] == 'X'))
  203.           me->me_dev = xatoi (devopt + 6);
  204.         else
  205.           me->me_dev = xatoi (devopt + 4);
  206.       }
  207.     else
  208.       me->me_dev = -1;    /* Magic; means not known yet. */
  209.     me->me_next = NULL;
  210.  
  211.     /* Add to the linked list. */
  212.     mtail->me_next = me;
  213.     mtail = me;
  214.       }
  215.  
  216.     if (endmntent (fp) == 0)
  217.       return NULL;
  218.   }
  219. #endif /* MOUNTED_GETMNTENT1. */
  220.  
  221. #ifdef MOUNTED_GETMNTINFO    /* 4.4BSD.  */
  222.   {
  223.     struct statfs *fsp;
  224.     int entries;
  225.  
  226.     entries = getmntinfo (&fsp, MNT_NOWAIT);
  227.     if (entries < 0)
  228.       return NULL;
  229.     while (entries-- > 0)
  230.       {
  231.     me = (struct mount_entry *) xmalloc (sizeof (struct mount_entry));
  232.     me->me_devname = xstrdup (fsp->f_mntfromname);
  233.     me->me_mountdir = xstrdup (fsp->f_mntonname);
  234.     me->me_type = fstype_to_string (fsp->f_type);
  235.     me->me_dev = -1;    /* Magic; means not known yet. */
  236.     me->me_next = NULL;
  237.  
  238.     /* Add to the linked list. */
  239.     mtail->me_next = me;
  240.     mtail = me;
  241.     fsp++;
  242.       }
  243.   }
  244. #endif /* MOUNTED_GETMNTINFO */
  245.  
  246. #ifdef MOUNTED_GETMNT        /* Ultrix.  */
  247.   {
  248.     int offset = 0;
  249.     int val;
  250.     struct fs_data fsd;
  251.  
  252.     while ((val = getmnt (&offset, &fsd, sizeof (fsd), NOSTAT_MANY,
  253.               (char *) 0)) > 0)
  254.       {
  255.     me = (struct mount_entry *) xmalloc (sizeof (struct mount_entry));
  256.     me->me_devname = xstrdup (fsd.fd_req.devname);
  257.     me->me_mountdir = xstrdup (fsd.fd_req.path);
  258.     me->me_type = gt_names[fsd.fd_req.fstype];
  259.     me->me_dev = fsd.fd_req.dev;
  260.     me->me_next = NULL;
  261.  
  262.     /* Add to the linked list. */
  263.     mtail->me_next = me;
  264.     mtail = me;
  265.       }
  266.     if (val < 0)
  267.       return NULL;
  268.   }
  269. #endif /* MOUNTED_GETMNT. */
  270.  
  271. #if defined (MOUNTED_FREAD) || defined (MOUNTED_FREAD_FSTYP) /* SVR[23].  */
  272.   {
  273.     struct mnttab mnt;
  274.     char *table = "/etc/mnttab";
  275.     FILE *fp;
  276.  
  277.     fp = fopen (table, "r");
  278.     if (fp == NULL)
  279.       return NULL;
  280.  
  281.     while (fread (&mnt, sizeof mnt, 1, fp) > 0)
  282.       {
  283.     me = (struct mount_entry *) xmalloc (sizeof (struct mount_entry));
  284. #ifdef GETFSTYP            /* SVR3.  */
  285.     me->me_devname = xstrdup (mnt.mt_dev);
  286. #else
  287.     me->me_devname = xmalloc (strlen (mnt.mt_dev) + 6);
  288.     strcpy (me->me_devname, "/dev/");
  289.     strcpy (me->me_devname + 5, mnt.mt_dev);
  290. #endif
  291.     me->me_mountdir = xstrdup (mnt.mt_filsys);
  292.     me->me_dev = -1;    /* Magic; means not known yet. */
  293.     me->me_type = "";
  294. #ifdef GETFSTYP            /* SVR3.  */
  295.     if (need_fs_type)
  296.       {
  297.         struct statfs fsd;
  298.         char typebuf[FSTYPSZ];
  299.  
  300.         if (statfs (me->me_mountdir, &fsd, sizeof fsd, 0) != -1
  301.         && sysfs (GETFSTYP, fsd.f_fstyp, typebuf) != -1)
  302.           me->me_type = xstrdup (typebuf);
  303.       }
  304. #endif
  305.     me->me_next = NULL;
  306.  
  307.     /* Add to the linked list. */
  308.     mtail->me_next = me;
  309.     mtail = me;
  310.       }
  311.  
  312.     if (fclose (fp) == EOF)
  313.       return NULL;
  314.   }
  315. #endif /* MOUNTED_FREAD || MOUNTED_FREAD_FSTYP.  */
  316.  
  317. #ifdef MOUNTED_GETMNTENT2    /* SVR4.  */
  318.   {
  319.     struct mnttab mnt;
  320.     char *table = MNTTAB;
  321.     FILE *fp;
  322.     int ret;
  323.  
  324.     fp = fopen (table, "r");
  325.     if (fp == NULL)
  326.       return NULL;
  327.  
  328.     while ((ret = getmntent (fp, &mnt)) == 0)
  329.       {
  330.     me = (struct mount_entry *) xmalloc (sizeof (struct mount_entry));
  331.     me->me_devname = xstrdup (mnt.mnt_special);
  332.     me->me_mountdir = xstrdup (mnt.mnt_mountp);
  333.     me->me_type = xstrdup (mnt.mnt_fstype);
  334.     me->me_dev = -1;    /* Magic; means not known yet. */
  335.     me->me_next = NULL;
  336.  
  337.     /* Add to the linked list. */
  338.     mtail->me_next = me;
  339.     mtail = me;
  340.       }
  341.  
  342.     if (ret > 0)
  343.       return NULL;
  344.    if (fclose (fp) == EOF)
  345.       return NULL;
  346.   }
  347. #endif /* MOUNTED_GETMNTENT2.  */
  348.  
  349. #ifdef MOUNTED_VMOUNT        /* AIX.  */
  350.   {
  351.     int bufsize;
  352.     char *entries, *thisent;
  353.     struct vmount *vmp;
  354.  
  355.     /* Ask how many bytes to allocate for the mounted filesystem info.  */
  356.     mntctl (MCTL_QUERY, sizeof bufsize, (struct vmount *) &bufsize);
  357.     entries = xmalloc (bufsize);
  358.  
  359.     /* Get the list of mounted filesystems.  */
  360.     mntctl (MCTL_QUERY, bufsize, (struct vmount *) entries);
  361.  
  362.     for (thisent = entries; thisent < entries + bufsize;
  363.      thisent += vmp->vmt_length)
  364.       {
  365.     vmp = (struct vmount *) thisent;
  366.     me = (struct mount_entry *) xmalloc (sizeof (struct mount_entry));
  367.     if (vmp->vmt_flags & MNT_REMOTE)
  368.       {
  369.         char *host, *path;
  370.  
  371.         /* Prepend the remote pathname.  */
  372.         host = thisent + vmp->vmt_data[VMT_HOSTNAME].vmt_off;
  373.         path = thisent + vmp->vmt_data[VMT_OBJECT].vmt_off;
  374.         me->me_devname = xmalloc (strlen (host) + strlen (path) + 2);
  375.         strcpy (me->me_devname, host);
  376.         strcat (me->me_devname, ":");
  377.         strcat (me->me_devname, path);
  378.       }
  379.     else
  380.       {
  381.         me->me_devname = xstrdup (thisent + 
  382.                       vmp->vmt_data[VMT_OBJECT].vmt_off);
  383.       }
  384.     me->me_mountdir = xstrdup (thisent + vmp->vmt_data[VMT_STUB].vmt_off);
  385.     me->me_type = xstrdup (fstype_to_string (vmp->vmt_gfstype));
  386.     me->me_dev = -1;    /* vmt_fsid might be the info we want.  */
  387.     me->me_next = NULL;
  388.  
  389.     /* Add to the linked list. */
  390.     mtail->me_next = me;
  391.     mtail = me;
  392.       }
  393.     free (entries);
  394.   }
  395. #endif /* MOUNTED_VMOUNT. */
  396.  
  397.   /* Free the dummy head. */
  398.   me = mount_list;
  399.   mount_list = mount_list->me_next;
  400.   free (me);
  401.   return mount_list;
  402. }
  403.